package org.example.zxing;

import com.google.zxing.*;
import com.google.zxing.common.GlobalHistogramBinarizer;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.multi.MultipleBarcodeReader;
import com.google.zxing.multi.GenericMultipleBarcodeReader;
import com.google.zxing.oned.EAN13Reader;
import org.apache.commons.lang3.CharSet;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.nio.charset.Charset;
import java.util.*;

public class ZXingTest {

    public static final String basepath = "D:\\work\\workspace\\PaddlePaddle\\PaddleOCR-release-2.4\\train_data\\barcode\\barcode\\";

    private static final Map<DecodeHintType, Object> HINTS;

    static {
        HINTS = new EnumMap<DecodeHintType, Object>(DecodeHintType.class);
        // 优化精度
        HINTS.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
        HINTS.put(DecodeHintType.POSSIBLE_FORMATS, EnumSet.allOf(BarcodeFormat.class));
        // 解码设置编码方式为：utf-8
        HINTS.put(DecodeHintType.CHARACTER_SET, "UTF-8");
        // 复杂模式，开启PURE_BARCODE模式
        HINTS.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE);
    }

    public static void main(String[] args) throws Exception {
        // error
//         processImg(basepath + "img_01.jpg");
//        processImg(basepath + "img_02.jpg");
//        processImg(basepath + "img_03.jpg");
//        processImg(basepath + "img_04.jpg");
//         processImg(basepath + "img_05.jpg");
//        processImg(basepath + "img_06.jpg");
//        processImg(basepath + "img_07.jpg");
//        processImg(basepath + "img_08.jpg");
//        processImg(basepath + "img_09.jpg");
//        processImg(basepath + "img_10.jpg");
        // processImg(basepath + "img_11.jpg");
        // error
//        processImg(basepath + "img_12.jpg");
        //processImg(basepath + "img_13.jpg");
        // processImg("D:\\JetBrains\\PyCharmCommunityEdition2021.2.3\\workspace\\PytorchDemo\\paddle\\ppocr_img\\imgs\\qrcode\\2021120316191810.png");

        processImg(basepath + "img_18.png");
        processImg(basepath + "img_19.png");
        processImg(basepath + "img_20.png");
    }

    public static void processImg(String filepath) throws Exception {
        BufferedImage image;
        FileInputStream fins = new FileInputStream(new File(filepath));
        try {
            image = ImageIO.read(fins);
        } catch (Exception e) {
            return;
        }

        LuminanceSource source = new BufferedImageLuminanceSource(image);
        BinaryBitmap bitmap = new BinaryBitmap(new GlobalHistogramBinarizer(source));
        Collection<Result> results = new ArrayList<>(1);

        Reader reader = new MultiFormatReader();

        Exception error;

        try {
            MultipleBarcodeReader multiReader = new GenericMultipleBarcodeReader(reader);
            Result[] theResults = multiReader.decodeMultiple(bitmap, HINTS);
            if (theResults != null) {
                results.addAll(Arrays.asList(theResults));
            }

            for (Result result : results) {
                System.out.println(result.getText());
            }
            return;
        } catch (Exception e) {
            error = e;
        }

        if (results.isEmpty()) {
            try {
                // Look for normal barcode in photo
                Result theResult = reader.decode(bitmap, HINTS);
                if (theResult != null) {
                    results.add(theResult);
                }
            } catch (ReaderException re) {
                error = re;
            }
        }

        if (results.isEmpty()) {
            try {
                // Try again with other binarizer
                BinaryBitmap hybridBitmap = new BinaryBitmap(new HybridBinarizer(source));
                Result theResult = reader.decode(hybridBitmap, HINTS);
                if (theResult != null) {
                    results.add(theResult);
                }
            } catch (ReaderException re) {
                error = re;
            }
        }

        if (results.isEmpty()) {
            throw error;
        }
    }
}
